home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / progutil / stdwin.zoo / atari / menu.c < prev    next >
C/C++ Source or Header  |  1990-03-29  |  11KB  |  618 lines

  1. #include "window.h"
  2. #include "trees.h"
  3. #include "atari_proto.h"
  4. #undef P
  5.  
  6. static int    deflocal = FALSE ;
  7. static struct menubar    globmenus ;
  8.  
  9. static int    barchanged = FALSE ;
  10.  
  11. static struct ln    m_link[256] ;
  12.  
  13. static OBJECT    *menu = NULL ;
  14.  
  15. extern int    scr_width ;
  16. extern int    scr_height ;
  17.  
  18. extern WINDOW    **winlist ;
  19. extern WINDOW    *active ;
  20. extern int    nrwin ;
  21.  
  22. void
  23. initmbar (win)
  24.     WINDOW    *win ;
  25. {
  26.     int    i ;
  27.  
  28.     L_INIT (win->mbar.nrmenus, win->mbar.menulist) ;
  29.  
  30.     for (i = 0 ; i < globmenus.nrmenus ; i++)
  31.         wmenuattach (win, globmenus.menulist[i]) ;
  32. }
  33.  
  34. void
  35. initglobmenus ()
  36. {
  37.     MENU    *pm ;
  38.     int    i ;
  39.  
  40.     L_INIT (globmenus.nrmenus, globmenus.menulist) ;
  41.  
  42.     wmenusetdeflocal (FALSE) ;
  43.  
  44.     pm = wmenucreate (0, "Desk") ;
  45.     (void) wmenuadditem (pm, "About STDWIN...", -1) ;
  46.     (void) wmenuadditem (pm, "", -1) ;
  47.  
  48.     for (i = 0 ; i < 6 ; i++)
  49.         (void) wmenuadditem (pm, "Desk Acc. Slot", -1) ;
  50. }
  51.  
  52. void
  53. addtobar (pbar, pm)
  54.     struct menubar    *pbar ;
  55.     MENU    *pm ;
  56. {
  57.     int    i ;
  58.  
  59.     for (i = 0 ; i < pbar->nrmenus ; i++) {
  60.         if (pbar->menulist[i] == pm)
  61.             return ;
  62.     }
  63.  
  64.     L_APPEND (pbar->nrmenus, pbar->menulist, MENU *, pm) ;
  65. }
  66.  
  67. void
  68. delofbar (pbar, pm)
  69.     struct menubar    *pbar ;
  70.     MENU    *pm ;
  71. {
  72.     int    i ;
  73.  
  74.     for (i = 0 ; i < pbar->nrmenus ; i++) {
  75.         if (pbar->menulist[i] == pm) {
  76.             L_REMOVE (pbar->nrmenus, pbar->menulist, MENU *, i) ;
  77.             break ;
  78.         }
  79.     }
  80. }
  81.  
  82. void
  83. addtoall (pm)
  84.     MENU    *pm ;
  85. {
  86.     int    i ;
  87.  
  88.     addtobar (&globmenus, pm) ;
  89.  
  90.     for (i = 0 ; i < nrwin ; i++)
  91.         wmenuattach (winlist[i], pm) ;
  92. }
  93.  
  94. MENU
  95. *wmenucreate (id, title)
  96.     int    id ;
  97.     char    *title ;
  98. {
  99.     MENU    *pm ;
  100.     char    buf[20] ;
  101.  
  102.     pm = ALLOC (MENU) ;
  103.  
  104.     if (pm == NULL)
  105.         return (NULL) ;
  106.  
  107.     pm->id = id ;
  108.     sprintf (buf, " %s ", title) ;
  109.     pm->title = strdup (buf) ;
  110.     pm->local = deflocal ;
  111.     pm->maxlen = 0 ;
  112.     L_INIT (pm->nritems, pm->itemlist) ;
  113.     if (!pm->local)
  114.         addtoall (pm) ;
  115.     return (pm) ;
  116. }
  117.  
  118. void
  119. wmenusetdeflocal (flag)
  120.     int    flag ;
  121. {
  122.     deflocal = flag ;
  123. }
  124.  
  125. void
  126. wmenuattach (win, pm)
  127.     WINDOW    *win ;
  128.     MENU    *pm ;
  129. {
  130.     addtobar (&win->mbar, pm) ;
  131.     if (win == active)
  132.         barchanged = TRUE ;
  133. }
  134.  
  135. void
  136. wmenudetach (win, pm)
  137.     WINDOW    *win ;
  138.     MENU    *pm ;
  139. {
  140.     delofbar (&win->mbar, pm) ;
  141.     if (win == active)
  142.         barchanged = TRUE ;
  143. }
  144.  
  145. void
  146. wmenudelete (pm)
  147.     MENU    *pm ;
  148. {
  149.     int    i ;
  150.  
  151.     delofbar (&globmenus, pm) ;
  152.  
  153.     for (i = 0 ; i < nrwin ; i++)
  154.         wmenudetach (winlist[i], pm) ;
  155.  
  156.     for (i = 0 ; i < pm->nritems ; i++) {
  157.         FREE (pm->itemlist[i]->ittext) ;
  158.         FREE (pm->itemlist[i]->sctext) ;
  159.         FREE (pm->itemlist[i]->line) ;
  160.     }
  161.     L_DEALLOC (pm->nritems, pm->itemlist) ;
  162.     FREE (pm) ;
  163. }
  164.  
  165. int
  166. wmenuadditem (pm, str, shortcut)
  167.     MENU    *pm ;
  168.     char    *str ;
  169.     int    shortcut ;
  170. {
  171.     struct m_item    *it = ALLOC (struct m_item) ;
  172.     int    len = 0 ;
  173.     char    buf[50] ;
  174.  
  175.     barchanged = TRUE ;
  176.  
  177.      it->ittext = strdup (str) ;
  178.     it->checked = FALSE ;
  179.     it->enabled = str != NULL && *str != 0 ;
  180.  
  181.     if (it->enabled)
  182.         len = 2 + (int)strlen (it->ittext) ;
  183.  
  184.     if (shortcut > -1) {
  185.         sprintf (buf, "Alt-%c", shortcut) ;
  186.         it->sctext = strdup (buf) ;
  187.         setkey (pm->id, pm->nritems, shortcut) ;
  188.  
  189.         len += (2 + (int)strlen (it->sctext)) ;
  190.     }
  191.     else
  192.         it->sctext = NULL ;
  193.  
  194.     it->line = NULL ;
  195.  
  196.     L_APPEND (pm->nritems, pm->itemlist, struct m_item *, it) ;
  197.  
  198.     if (++len > pm->maxlen)
  199.         pm->maxlen = len ;
  200.  
  201.     pm->dirty = TRUE ;
  202.  
  203.     return (pm->nritems - 1) ;
  204. }
  205.  
  206. void
  207. wmenusetitem (pm, item, text)
  208.     MENU    *pm ;
  209.     int    item ;
  210.     char    *text ;
  211. {
  212.     struct m_item    *it ;
  213.     int    len = 0 ;
  214.  
  215.     if (item < 0 || item >= pm->nritems)
  216.         return ;
  217.  
  218.     it = pm->itemlist[item] ;
  219.  
  220.     FREE (it->ittext) ;
  221.  
  222.     pm->dirty = TRUE ;
  223.     it->enabled = text != NULL && *text != 0 ;
  224.  
  225.     if (it->enabled) {
  226.         it->ittext = strdup (text) ;
  227.  
  228.         len = 2 + (int)strlen (it->ittext) ;
  229.         if (it->sctext != NULL || *it->sctext != '\0')
  230.             len += 2 + (int)strlen (it->sctext) ;
  231.     }
  232.     else
  233.         it->checked = FALSE ;
  234.  
  235.     if (++len > pm->maxlen)
  236.         pm->maxlen = len ;
  237.  
  238.     barchanged = TRUE ;
  239. }
  240.  
  241. void
  242. wmenuenable (pm, item, flag)
  243.     MENU    *pm ;
  244.     int    item ;
  245.     bool    flag ;
  246. {
  247.     struct m_item    *it ;
  248.  
  249.     if (item < 0 || item >= pm->nritems)
  250.         return ;
  251.  
  252.     it = pm->itemlist[item] ;
  253.  
  254.     if (it->enabled == flag)
  255.         return ;
  256.  
  257.     it->enabled = flag ;
  258.  
  259.     if (menu != NULL) {
  260.         int    obj = 4 ;
  261.         int    i ;
  262.  
  263.         for (i = 0 ; i < active->mbar.nrmenus ; ++i) {
  264.             MENU    *mp = active->mbar.menulist[i] ;
  265.  
  266.             if (pm == mp)
  267.                 break ;
  268.  
  269.             obj += mp->nritems + 1 ;
  270.         }
  271.  
  272.         obj += item + 1 + active->mbar.nrmenus ;
  273.         menu_ienable (menu, obj, it->enabled) ;
  274.     }
  275. }
  276.  
  277. void
  278. wmenucheck (pm, item, flag)
  279.     MENU    *pm ;
  280.     int    item ;
  281.     bool    flag ;
  282. {
  283.     struct m_item    *it ;
  284.  
  285.     if (item < 0 || item >= pm->nritems)
  286.         return ;
  287.  
  288.     it = pm->itemlist[item] ;
  289.  
  290.     if (it->checked == flag)
  291.         return ;
  292.  
  293.     it->checked = flag ;
  294.  
  295.     if (menu != NULL) {
  296.         int    obj = 4 ;
  297.         int    i ;
  298.  
  299.         for (i = 0 ; i < active->mbar.nrmenus ; ++i) {
  300.             MENU    *mp = active->mbar.menulist[i] ;
  301.  
  302.             if (pm == mp)
  303.                 break ;
  304.  
  305.             obj += mp->nritems + 1 ;
  306.         }
  307.  
  308.         obj += item + 1 + active->mbar.nrmenus ;
  309.         menu_icheck (menu, obj, it->checked) ;
  310.     }
  311. }
  312.  
  313. OBJECT
  314. *buildbar (win)
  315.     WINDOW    *win ;
  316. {
  317.     TREE    tree = { 0, 0, 0 } ;
  318.     TREE    *t = &tree ;
  319.     int    act ;
  320.     int    scr ;
  321.     int    box ;
  322.     int    title ;
  323.     int    dummy = 0 ;
  324.     int    lh = wlineheight () ;
  325.     int    first = 1 ;
  326.     int    act_x = 2 * wcharwidth ('m') ;
  327.     int    m_width = 0 ;
  328.     int    s_height = 0 ;
  329.     int    i ;
  330.     int    j ;
  331.  
  332.     tr_add (t, 0, G_IBOX, NONE, NORMAL, 0L, 0, 0, scr_width, scr_height) ;
  333.     m_link[t->focus].m = m_link[t->focus].it = -1 ;
  334.  
  335.     tr_add (t, 1, G_BOX, NONE, NORMAL, BAR, 0, 0, scr_width, BAR_HEIGHT) ;
  336.     m_link[t->focus].m = m_link[t->focus].it = -1 ;
  337.  
  338.     tr_add (t, 1, G_IBOX, NONE, NORMAL, 0L, act_x, 0,
  339.                             dummy, BAR_HEIGHT) ;
  340.     act = t->focus ;
  341.     m_link[t->focus].m = m_link[t->focus].it = -1 ;
  342.  
  343.     for (i = 0 ; i < win->mbar.nrmenus ; i++) {
  344.         int    width ;
  345.         MENU    *pm = win->mbar.menulist[i] ;
  346.  
  347.         width = wtextwidth (pm->title, -1) ;
  348.  
  349.         tr_add (t, first, G_TITLE, NONE, NORMAL, pm->title, m_width, 0,
  350.                             width, BAR_HEIGHT) ;
  351.         m_width += width ;
  352.         m_link[t->focus].m = pm->id ;
  353.         m_link[t->focus].it = -1 ;
  354.         if (first)
  355.             first = 0 ;
  356.     }
  357.     t->obj[act].ob_width = m_width ;
  358.  
  359.     tr_parent (t) ;
  360.     tr_parent (t) ;
  361.  
  362.     tr_add (t, 0, G_IBOX, NONE, NORMAL, 0L, 0, BAR_HEIGHT, scr_width,
  363.                                     dummy) ;
  364.     scr = t->focus ;
  365.     m_link[t->focus].m = m_link[t->focus].it = -1 ;
  366.  
  367.     first = 1 ;
  368.     title = t->obj[act].ob_head ;
  369.  
  370.     for (i = 0 ; i < win->mbar.nrmenus ; i++) {
  371.         int    firstit = 1 ;
  372.         int    b_width = 0 ;
  373.         int    box_x = t->obj[title].ob_x + t->obj[act].ob_x ;
  374.         MENU    *pm = win->mbar.menulist[i] ;
  375.  
  376.         if (pm->dirty)
  377.             checkmenu (pm) ;
  378.  
  379.         tr_add (t, first, G_BOX, NONE, NORMAL, BOX, box_x, 0,
  380.                                 dummy, dummy) ;
  381.         box = t->focus ;
  382.         m_link[t->focus].m = m_link[t->focus].it = -1 ;
  383.         for (j = 0 ; j < pm->nritems ; j++) {
  384.             struct m_item    *it = pm->itemlist[j] ;
  385.             int    width = wtextwidth (it->line, -1) ;
  386.             int    state = (it->enabled ? NORMAL : DISABLED) ;
  387.  
  388.             if (it->checked)
  389.                 state |= CHECKED ;
  390.  
  391.             tr_add (t, firstit, G_STRING, NONE, (long)state, it->line, 0,
  392.                             j * lh, width, lh) ;
  393.             if (width > b_width)
  394.                 b_width = width ;
  395.             m_link[t->focus].m = pm->id ;
  396.             m_link[t->focus].it = j ;
  397.             if (firstit)
  398.                 firstit = 0 ;
  399.         }
  400.         if (!firstit)
  401.             tr_parent (t) ;
  402.  
  403.         for (j = 0 ; j < pm->nritems ; j++) {
  404.             OBJECT    *o = &t->obj[t->focus + j + 1] ;
  405.  
  406.             o->ob_width = b_width ;
  407.         }
  408.         t->obj[box].ob_width = b_width ;
  409.         t->obj[box].ob_height = pm->nritems * lh ;
  410.         if (t->obj[box].ob_height > s_height )
  411.             s_height = t->obj[box].ob_height ;
  412.         if (first)
  413.             first = 0 ;
  414.         title = t->obj[title].ob_next ;
  415.     }
  416.  
  417.     t->obj[scr].ob_height = s_height ;
  418. /*    tr_dump (t) ;
  419. */    return (tr_tree (t)) ;
  420. }
  421. void
  422. checkmenu (pm)
  423.     MENU    *pm ;
  424. {
  425.     int    k ;
  426.  
  427.     for (k = 0 ; k < pm->nritems ; k++) {
  428.         struct m_item    *i = pm->itemlist[k] ;
  429.         char    buf[256] ;
  430.         char    *cp = buf ;
  431.         char    *text  = i->ittext ;
  432.         int    l ;
  433.  
  434.         if (i->line != NULL && (int)strlen (i->line) == pm->maxlen)
  435.             continue ;
  436.  
  437.         FREE (i->line) ;
  438.  
  439.         if (text == NULL)
  440.             text = "" ;
  441.  
  442.         if (*text == '\0') {
  443.             for (l = 0 ; l < pm->maxlen ; ++l)
  444.                 *cp++ = '-' ;
  445.             *cp = '\0' ;
  446.         }
  447.         else {
  448.             l = 2 + (int)strlen (text) ;
  449.             sprintf (cp, "  %s", text) ;
  450.             cp += l ;
  451.  
  452.             text = i->sctext ;
  453.             if (text != NULL) {
  454.                 l += (int)strlen (text) ;
  455.                 while (l < pm->maxlen - 1) {
  456.                     ++l ;
  457.                     *cp++ = ' ' ;
  458.                 }
  459.                 strcpy (cp, text) ;
  460.                 cp += (int)strlen (cp) ;
  461.             }
  462.             strcat (cp, " ") ;
  463.         }
  464.         i->line = strdup (buf) ;
  465.     }
  466.     pm->dirty = FALSE ;
  467. }
  468.  
  469. void
  470. menuupda